package baseFx.common.file;

import baseFx.common.Assert;
import baseFx.common.Env;
import baseFx.common.utils.ExceptionUtils;
import baseFx.common.utils.StringUtils;

import java.io.*;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

public class FilespaceByLocal implements Filespace {
    private String dir;
    private String host;

    public FilespaceByLocal(String dir, String host) {
        Assert.isNotNull(dir);
        if (host == null) {
            host = "";
        }
        this.dir = StringUtils.trimRight(dir, "/");
        this.host = StringUtils.trimRight(host, "/");
    }

    private String format(String path) {
        if (path.startsWith("/") == false) {
            path = "/" + path;
        }
        path = dir + path;
        return path.replace("/", Env.fileSeparator());
    }

    @Override
    public void save(String path, InputStream stream) {
        String filePath = format(path);
        File file = new File(filePath);
        File dir = new File(file.getParent());
        if (dir.exists() == false) {
            if (dir.mkdirs() == false) {
                throw new RuntimeException("创建失败：" + path);
            }
        }
        try (OutputStream out = new FileOutputStream(file)) {
            int len;
            byte[] data = new byte[4096];
            while ((len = stream.read(data, 0, data.length)) > 0) {
                out.write(data, 0, len);
            }
        } catch (IOException e) {
            throw ExceptionUtils.toRuntime(e);
        }
    }

    @Override
    public String getUri(String path) {
        if (path.startsWith("/") == false) {
            path = "/" + path;
        }
        return host + path;
    }

    @Override
    public InputStream getFile(String path) {
        try {
            return new FileInputStream(format(path));
        } catch (FileNotFoundException e) {
            return null;
        }
    }

    public String getFullPath(String path) {
        return format(path);
    }

    @Override
    public void remove(String path) {
        String filePath = format(path);
        File file = new File(filePath);
        if (file.isFile() && file.exists()) {
            if (file.delete() == false) {
                throw new RuntimeException("删除失败：" + path);
            }
        } else {
            throw new RuntimeException("不是文件或者文件不存在");
        }
    }

    @Override
    public void move(String src, String dest) {
        File sFile = new File(format(src));
        if (!(sFile.isFile() && sFile.exists())) {
            throw new RuntimeException("不是文件或者文件不存在");
        }
        try {
            File dFile = new File(format(dest));
            if (dFile.getParentFile().exists() == false) {
                if (dFile.getParentFile().mkdirs() == false) {
                    throw new RuntimeException("目录创建失败");
                }
            }
            Files.move(sFile.toPath(), dFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void copy(String src, String dest) {
        File sFile = new File(format(src));
        if (!(sFile.isFile() && sFile.exists())) {
            throw new RuntimeException("不是文件或者文件不存在");
        }
        try {
            File dFile = new File(format(dest));
            if (dFile.getParentFile().exists() == false) {
                if (dFile.getParentFile().mkdirs() == false) {
                    throw new RuntimeException("目录创建失败");
                }
            }
            Files.copy(sFile.toPath(), dFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
